package com.education.service.trade.service.impl;

import com.education.common.utils.HttpClientUtils;
import com.education.exception.OnlineEducationException;
import com.education.result.ResultCodeEnum;
import com.education.service.trade.entity.Order;
import com.education.service.trade.service.OrderService;
import com.education.service.trade.service.WeChatPayService;
import com.education.service.trade.utils.WeixinPayProperties;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付 - 业务实现
 * Created by Lance on 2020/07/10 20:56
 */
@Slf4j
@Service
public class WeChatPayServiceImpl implements WeChatPayService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private WeixinPayProperties weixinPayProperties;

    /**
     * 创建统一下单任务 - 调用远程下单接口
     * @param orderNo    订单号
     * @param remoteAddr 远程客户端地址
     * @return
     */
    @Override
    public Map<String, Object> createNative(String orderNo, String remoteAddr) {
        try {
            // 根据订单号获取订单
            Order order = orderService.getOrderByOrderNo(orderNo);
            // 调用统一下单接口 : 使用 httpClient
            HttpClientUtils httpClientUtils = new HttpClientUtils("https://api.mch.weixin.qq.com/pay/unifiedorder");

            // 组装接口参数
            Map<String, String> params = new HashMap<>();
            params.put("appid", weixinPayProperties.getAppId());//公众账号ID
            params.put("mch_id", weixinPayProperties.getPartner());//商户号
            params.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
            // 签名	sign：无需组装，发送请求的时候自动生成并称携带
            params.put("body", order.getCourseTitle()); //商品描述
            params.put("out_trade_no", orderNo);    //商户订单号
            params.put("total_fee", order.getTotalFee() + "");//标价金额
            params.put("spbill_create_ip", remoteAddr);//终端IP
            params.put("notify_url", weixinPayProperties.getNotifyUrl());//通知地址
            params.put("trade_type", "NATIVE");     //交易类型

            // 将 map 参数转换成xml格式的字符串
            String xml = WXPayUtil.generateSignedXml(params, weixinPayProperties.getPartnerKey());
            log.info("xml = \n" + xml);

            // 完成 httpClientUtils 对象的设置
            httpClientUtils.setXmlParam(xml);
            httpClientUtils.setHttps(true);
            httpClientUtils.post();

            // 获取响应
            String resultXml = httpClientUtils.getContent();

            // 分析返回结果
            Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);

            // 错误处理
            // 判断通信标识和业务标识 是否有问题
            if("FAIL".equals(resultMap.get("return_code")) || "FAIL".equals(resultMap.get("result_code"))){
                log.error("微信支付统一下单错误 - "
                        + "return_code: " + resultMap.get("return_code")
                        + "return_msg: " + resultMap.get("return_msg")
                        + "result_code: " + resultMap.get("result_code")
                        + "err_code: " + resultMap.get("err_code")
                        + "err_code_des: " + resultMap.get("err_code_des"));

                throw new OnlineEducationException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
            }

            // 返回客户端需要的内容 [ 二维码 URL - 订单金额 - 订单号信息 - 课程信息 ]
            Map<String, Object> map = new HashMap<>();
            map.put("result_code", resultMap.get("result_code"));   // 响应码
            map.put("code_url", resultMap.get("code_url")); // 生成二维码的url
            map.put("course_id", order.getCourseId());  // 课程id
            map.put("total_fee", order.getTotalFee());  // 订单总金额
            map.put("out_trade_no", orderNo);   // 订单号
            return map;

        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new OnlineEducationException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
        }
    }
}
